library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;			--   (un)signed
use std.TextIO.all; 

package constants is	
constant progMemSizeBits : integer := 8;	
	
subtype b32 is std_logic_vector(31 downto 0);
subtype b5 is std_logic_vector(4 downto 0);
subtype RegSelType is std_logic_vector(4 downto 0);
subtype FuncType is std_logic_vector(5 downto 0);
subtype AluOpType is std_logic_vector(4 downto 0);
subtype ClassType is std_logic_vector(1 downto 0);
subtype CondType is std_logic_vector(3 downto 0);

constant CLASS_ALU :  ClassType  := "01";
constant CLASS_LDST :  ClassType := "10";
constant CLASS_JUMP :  ClassType := "11";

constant F_JUMP_REL	:  FuncType := "00" & x"1";-- jump pc relative
constant F_JUMP_ABS	:  FuncType := "00" & x"2"; -- jump absolut
constant F_LDST_LOAD :  FuncType := "00" & x"0"; -- load
constant F_LDST_STORE :  FuncType := "00" & x"1"; -- store

constant ALU_PASS_B: AluOpType		:= "00001"; 
constant ALU_NEG: AluOpType			:= "00010"; 
constant ALU_ADD: AluOpType			:= "00011"; 
constant ALU_SUB: AluOpType			:= "00100"; 
constant ALU_AND: AluOpType			:= "00101"; 
constant ALU_OR: AluOpType			:= "00110"; 
constant ALU_NAND: AluOpType		:= "00111"; 
constant ALU_XOR: AluOpType			:= "01000"; 
constant ALU_NOT: AluOpType			:= "01001"; 
constant ALU_SHIFT_L: AluOpType		:= "01010"; 
constant ALU_SHIFT_R: AluOpType		:= "01011"; 
constant ALU_SHIFT_A: AluOpType		:= "01100";
constant ALU_SWAP16: AluOpType		:= "01101";
constant ALU_SWAP8: AluOpType		:= "01110";
constant ALU_BYTE_SWAP: AluOpType	:= "01111";

--constant COND_NEVER  : CondType := x"0";

constant C_EQ	 : std_logic_vector(2 downto 0) := "001";
constant C_LESS   : std_logic_vector(2 downto 0) := "010";
constant C_GREATER: std_logic_vector(2 downto 0) := "011";
constant C_CARRY  : std_logic_vector(2 downto 0) := "100";

constant COND_ALWAYS : CondType := x"F";
constant COND_NEVER : CondType := x"0";
constant COND_EQUAL : CondType  := '1' & C_EQ;
constant COND_NEQUAL : CondType := '0' & C_EQ;
constant COND_LESS  : CondType := '1' & C_LESS;
constant COND_GR_EQ : CondType := '0' & C_LESS;
constant COND_GREATER : CondType  := '1' & C_GREATER;
constant COND_L_EQ : CondType  := '0' & C_GREATER;
constant COND_CARRY : CondType  := '1' & C_CARRY;
constant COND_NCARRY : CondType  := '0' & C_CARRY;

constant r0 : RegSelType := (others => '0');
constant r1 : RegSelType := std_logic_vector(to_unsigned(1, RegSelType'length));
constant r2 : RegSelType := std_logic_vector(to_unsigned(2, RegSelType'length));
constant r3 : RegSelType := std_logic_vector(to_unsigned(3, RegSelType'length));
constant r4 : RegSelType := std_logic_vector(to_unsigned(4, RegSelType'length));
constant r5 : RegSelType := std_logic_vector(to_unsigned(5, RegSelType'length));
constant r6 : RegSelType := std_logic_vector(to_unsigned(5, RegSelType'length));

constant UNUSED4 : std_logic_vector(3 downto 0) := "0000";

constant NOP: std_logic_vector(31 downto 0) 
	-- mov r0, r0
	:= "0000" & CLASS_ALU & '1' & "0000" & '0' & ALU_PASS_B & r0 & r0 & r0; 		

function to_std_logic(c: character) return std_logic;
function to_std_logic_vector(s: string) return std_logic_vector;
	
end constants;
												  
package body constants is
	function to_std_logic(c: character) return std_logic is 
	    variable sl: std_logic;
	    begin
	      case c is
	        when 'U' => 
	           sl := 'U'; 
	        when 'X' =>
	           sl := 'X';
	        when '0' => 
	           sl := '0';
	        when '1' => 
	           sl := '1';
	        when 'Z' => 
	           sl := 'Z';
	        when 'W' => 
	           sl := 'W';
	        when 'L' => 
	           sl := 'L';
	        when 'H' => 
	           sl := 'H';
	        when '-' => 
	           sl := '-';
	        when others =>
	           sl := 'X'; 
	    end case;
	   return sl;
	  end to_std_logic;
	
	
	-- converts a string into std_logic_vector
	
	function to_std_logic_vector(s: string) return std_logic_vector is 
	  variable slv: std_logic_vector(s'high-s'low downto 0);
	  variable k: integer;
	begin
	   k := s'high-s'low;
	  for i in s'range loop
	     slv(k) := to_std_logic(s(i));
	     k      := k - 1;
	  end loop;
	  return slv;
	end to_std_logic_vector;	
	
	
	
	
end package body;
            	